package org.hs.phd.odi.tracking.tracker.trackwindow;

import java.awt.Polygon;
import java.awt.geom.Point2D;
import java.awt.geom.Point2D.Float;
import java.awt.geom.Rectangle2D;

import org.hs.phd.common.improc.traversal.PixelTraversalKit;
import org.hs.phd.common.improc.traversal.RGBImagePixelProcessor;
import org.hs.phd.common.improc.traversal.RGBImagePixelTraverser;
import org.hs.phd.odi.tracking.tracker.TrackWindow;

import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class RegularGridPolygonalTrackWindow extends AbstractRegularGridTrackWindow {
	
	private Polygon polygon;

	public RegularGridPolygonalTrackWindow(){
		polygon = new Polygon();
	}
	
	@Override
	public void traversePixels(IplImage frame, RGBImagePixelProcessor processor) {
		RGBImagePixelTraverser traverser = PixelTraversalKit.createRGBPolygonalTraverser(polygon);
		traverser.traversePixels(frame, processor);
	}

	@Override
	public void moveToBestMatchingLocationFor(Polygon initialTrackShape) {
		polygon = getPolygonCopy(initialTrackShape);
	}

	private static Polygon getPolygonCopy(Polygon p) {
		Polygon copy = new Polygon();
		for(int i = 0; i < p.npoints; i++){
			copy.addPoint(p.xpoints[i], p.ypoints[i]);
		}
		return copy;
	}

	@Override
	public void moveCenterToPosition(Float newPosition) {
		Float currentCenter = getCenter();
		
		int deltaX = (int)(newPosition.getX() - currentCenter.getX());
		int deltaY = (int)(newPosition.getY() - currentCenter.getY());
		polygon.translate(deltaX, deltaY);
	}

	@Override
	public Polygon getAsPolygon() {
		return getPolygonCopy(polygon);
	}

	@Override
	public Float getCenter() {
		Rectangle2D bounds2d = polygon.getBounds2D();
		return new Point2D.Float((float)bounds2d.getCenterX(), (float)bounds2d.getCenterY());
	}

	@Override
	public TrackWindow getCopy() {
		RegularGridPolygonalTrackWindow copy = new RegularGridPolygonalTrackWindow();
		copy.polygon = getPolygonCopy(polygon);
		return copy;
	}

	@Override
	public float normalizedDistanceFromGridCenterTo(float x, float y) {
		Float gridCenter = getGridCenter();
		
		Rectangle2D bounds2d = polygon.getBounds2D();

		float hx = (float) (bounds2d.getWidth()/2.0f);
		float hy = (float) (bounds2d.getHeight()/2.0f);
		
		float dx = (x - gridCenter.x)/hx;
		float dy = (y - gridCenter.y)/hy;

		return (float)Math.sqrt(dx*dx + dy*dy);
	}

}
